#!usr/bin/env python  
# -*- coding:utf-8 _*-
""" 
@author:robot
@file: ct_inspect_check.py 
@version:
@time: 2022/04/19 
"""
import time

from TapClientCore.T07_CaseTemplate.v2.CT03_task.ct_task import *


class CTTaskInspectCheck(CTTask):

    @staticmethod
    def inspects_func_wait(func1, func2, func3, args, compare, timeout=timeout_config):
        """
        :param func1: 校验状态
        :param func2: 校验结果
        :param func3: 校验总行数
        :param args: 校验任务名
        :param compare: 校验总行数比对值
        :param timeout: 超时时间
        :return:
        """
        with allure.step('事件统计'):
            for i in range(timeout):
                time.sleep(5)
                result1 = func1(args)
                if result1 == 'done':
                    logger.info(f'inspect status  is {result1} ')
                    result2 = func2(args)
                    if result2 == 'passed':
                        logger.info(f'inspect result is {result2}')
                        result3 = func3(args)
                        if result3 == compare:
                            logger.info(f'inspect source_total is {result3}')
                            assert True
                            return
                        else:
                            logger.info(f'inspect source_total is {result3}')
                            assert False
                    else:
                        logger.info(f'inspect result  is {result2} ')
                        assert False
                elif result1 == 'error':
                    logger.info(f'inspect status  is {result1} ')
                    assert False
                else:
                    pass
            raise TimeoutError

    def generate_inspect_url(self, task_name):
        with allure.step('生成校验结果url'):
            self._generate_inspect_url_by_name(task_name)
        if self.inspect_url:
            allure.attach(f'<a href="{self.inspect_url}" target="_blank">点击此处跳转到inspect结果页面</a>',
                          'inspect结果url', allure.attachment_type.HTML)

    def TASK_INSPECT_TEMPLATE_INITIAL_CHECK(self, parallel_data):
        data = None
        record_id = None
        task_name = None
        # 随机等待
        self.random_wait()
        try:
            data = self.lock_and_only_get_table(parallel_data)
            record_id = data.get('id')

            operate = data.pop('operate')
            operate_source = operate.get('source')
            source_info = operate_source.get('source_info')
            source_table = operate_source.get('table')
            operate_target = operate.get('target')
            target_info = operate_target.get('target_info')
            target_table = operate_target.get('table')

            if type(source_table) is list:
                pass
            else:
                data['task_config']['config']['name'] += source_table
            with allure.step('创建表获取'):
                task_name = data.get('task_config').get('config').get('name')

            # connector
            with allure.step('源数据库初始化'):
                _source = self.init_connector(source_info)
            with allure.step('目标数据库初始化'):
                _target = self.init_connector(target_info)
            _source.tapclient_connector.CURRENT_TABLE = source_table
            _target.tapclient_connector.CURRENT_TABLE = target_table

            source_where_column = operate_source.get('where')

            # stats check
            _stats = operate.get('stats_check').get('initial')
            _stats_initial = _stats.get('insert')
            # 多表处理
            if type(target_table) is list:
                self.drop_more_target_table(_target, target_table)
                source_delete = [_source.tapclient_connector.generate_delete(
                    source_where_column, moretableten
                ) for moretableten in source_table]
                with allure.step('执行前删除要插入的数据'):
                    _source.tapclient_connector.execMany(_source.tapclient_connector.exec, source_delete)
            else:
                self.drop_target_table(_target)
                source_delete = _source.tapclient_connector.generate_delete(
                    source_where_column
                )
                with allure.step('执行前删除要插入的数据'):
                    _source.tapclient_connector.exec(source_delete)
            # inspects info init
            inspect_init = {
                'source': source_info.get('name'),
                'target': target_info.get('name'),
                'table': target_table,
                'inspect_setting': {
                    # 'inspectMethod': 'field',
                    'inspectMethod': data.get('inspectMethod'),
                    'name': task_name
                }
            }

            with allure.step('创建任务'):
                task_info = self.create_data_copy_development(data)
                time.sleep(check_wait * 2)
                inspect_init['inspect_setting']['flowId'] = task_info.get('id')
            # initial stats insert 校验
            with allure.step('任务状态等待'):
                self.scheduled_task_wait_it_complete(task_name)
            self.release_table(record_id)
            self.func_wait(
                self.get_task_stats_insert,
                self.get_task_status,
                task_name,
                _stats_initial
            )
            with allure.step('initial数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_initial
                )
        finally:
            self.release_table(record_id)
            self.generate_task_url(task_name, data.get('task_type'))
            self.generate_inspect_url(task_name)
            logger.info(self.task_url)
            logger.info(self.inspect_url)
            try:
                _source.tapclient_connector.close()
                _target.tapclient_connector.close()
            except Exception as e:
                pass

    def TASK_INSPECT_TEMPLATE_CDC_CHECK(self, parallel_data):
        data = None
        # 随机等待
        self.random_wait()
        # 并行案例初始化
        data = self.lock_and_get_table(parallel_data)
        record_id = data.get('id')

        # operate info
        operate = data.pop('operate')
        operate_source = operate.get('source')
        operate_target = operate.get('target')
        source_info = operate_source.get('source_info')
        target_info = operate_target.get('target_info')

        # ddl and dml
        source_table = operate_source.get('table')
        source_insert_column = operate_source.get('insert')
        source_update_column = operate_source.get('update')
        source_where_column = operate_source.get('where')
        target_table = operate_target.get('table')

        data['task_config']['config']['name'] += source_table
        with allure.step('创建表获取'):
            task_name = data.get('task_config').get('config').get('name')
        # connector
        with allure.step('源数据库初始化'):
            _source = self.init_connector(source_info)
        with allure.step('目标数据库初始化'):
            _target = self.init_connector(target_info)
        _source.tapclient_connector.CURRENT_TABLE = source_table
        _target.tapclient_connector.CURRENT_TABLE = target_table
        source_insert = _source.tapclient_connector.generate_insert(
            source_insert_column
        )
        source_update = _source.tapclient_connector.generate_update(
            source_update_column,
            source_where_column
        )
        source_delete = _source.tapclient_connector.generate_delete(
            source_where_column
        )

        # stats check
        _stats = operate.get('stats_check').get('cdc')
        _stats_initial = _stats.get('initial')
        _stats_insert = _stats.get('insert')
        _stats_update = _stats.get('update')
        _stats_delete = _stats.get('delete')
        # target drop table
        self.drop_target_table(_target)
        # inspects info init
        inspect_init = {
            'source': source_info.get('name'),
            'target': target_info.get('name'),
            'table': target_table,
            'inspect_setting': {
                'inspectMethod': 'field',
                'name': task_name
            }
        }
        with allure.step('执行前删除要插入的数据'):
            _source.tapclient_connector.exec(source_delete)
        try:
            with allure.step('创建任务'):
                task_info = self.create_data_copy_development(data)
                time.sleep(check_wait * 2)
                inspect_init['inspect_setting']['flowId'] = task_info.get('id')
            with allure.step('等待任务运行'):
                self.scheduled_task_wait_it_running(task_name)
            # 增量任务等待时间
            logger.info('等待一段时间')
            time.sleep(180)
            # 增量阶段校验
            # insert
            logger.info('cdc insert and check')
            _source.tapclient_connector.exec(source_insert)
            self.func_wait(
                self.get_task_stats_insert,
                self.get_task_status,
                task_name,
                _stats_insert
            )
            with allure.step('insert数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_insert
                )
            # update
            _source.tapclient_connector.exec(source_update)
            self.func_wait(
                self.get_task_stats_update,
                self.get_task_status,
                task_name,
                _stats_update
            )
            with allure.step('update数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_update
                )
            # delete
            _source.tapclient_connector.exec(source_delete)
            self.func_wait(
                self.get_task_stats_delete,
                self.get_task_status,
                task_name,
                _stats_delete
            )
            with allure.step('delete数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_delete
                )
        except Exception as e:
            self.release_table(record_id)
            logger.info(e)
            _source.tapclient_connector.exec(source_delete)
            assert False
        finally:
            self.release_table(record_id)
            if self.task_is_running(task_name):
                self.stop_task_wait_it_paused(task_name)
            self.generate_task_url(task_name, data.get('task_type'))
            self.generate_inspect_url(task_name)
            logger.info(self.task_url)
            logger.info(self.inspect_url)
            try:
                _source.tapclient_connector.close()
                _target.tapclient_connector.close()
            except Exception as e:
                pass

    def TASK_INSPECT_TEMPLATE_INITIAL_CDC_CHECK(self, parallel_data):
        data = None
        # 随机等待
        self.random_wait()
        # 并行案例初始化
        data = self.lock_and_get_table(parallel_data)
        record_id = data.get('id')

        # operate info
        operate = data.pop('operate')
        operate_source = operate.get('source')
        operate_target = operate.get('target')
        source_info = operate_source.get('source_info')
        target_info = operate_target.get('target_info')
        # connector
        _source = self.init_connector(source_info)
        _target = self.init_connector(target_info)
        # ddl and dml
        source_table = operate_source.get('table')
        source_insert_column = operate_source.get('insert')
        source_update_column = operate_source.get('update')
        source_where_column = operate_source.get('where')
        target_table = operate_target.get('table')

        data['task_config']['config']['name'] += source_table
        task_name = data.get('task_config').get('config').get('name')

        _source.tapclient_connector.CURRENT_TABLE = source_table
        _target.tapclient_connector.CURRENT_TABLE = target_table
        source_insert = _source.tapclient_connector.generate_insert(
            source_insert_column
        )
        source_update = _source.tapclient_connector.generate_update(
            source_update_column,
            source_where_column
        )
        source_delete = _source.tapclient_connector.generate_delete(
            source_where_column
        )

        # stats check
        _stats = operate.get('stats_check').get('initial+cdc')
        _stats_initial = _stats.get('initial')
        _stats_insert = _stats.get('insert')
        _stats_update = _stats.get('update')
        _stats_delete = _stats.get('delete')
        # target drop table
        self.drop_target_table(_target)
        # inspects info init
        inspect_init = {
            'source': source_info.get('name'),
            'target': target_info.get('name'),
            'table': target_table,
            'inspect_setting': {
                'inspectMethod': 'field',
                'name': task_name
            }
        }
        with allure.step('执行前删除要插入的数据'):
            _source.tapclient_connector.exec(source_delete)
        try:
            with allure.step('创建任务'):
                task_info = self.create_data_copy_development(data)
                time.sleep(check_wait * 2)
                inspect_init['inspect_setting']['flowId'] = task_info.get('id')
            with allure.step('等待任务运行'):
                self.scheduled_task_wait_it_running(task_name)
            # 全量阶段校验
            logger.info('initial check')
            self.func_wait(
                self.get_task_stats_insert,
                self.get_task_status,
                task_name,
                _stats_initial
            )
            with allure.step('initial数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_initial
                )
            # insert
            logger.info('cdc insert and check')
            _source.tapclient_connector.exec(source_insert)
            self.func_wait(
                self.get_task_stats_insert,
                self.get_task_status,
                task_name,
                _stats_insert
            )
            with allure.step('insert数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_insert
                )
            # update
            _source.tapclient_connector.exec(source_update)
            self.func_wait(
                self.get_task_stats_update,
                self.get_task_status,
                task_name,
                _stats_update
            )
            with allure.step('update数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_insert
                )
            # delete
            _source.tapclient_connector.exec(source_delete)
            self.func_wait(
                self.get_task_stats_delete,
                self.get_task_status,
                task_name,
                _stats_delete
            )
            with allure.step('update数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_delete
                )
        except Exception as e:
            self.release_table(record_id)
            logger.info(e)
            _source.tapclient_connector.exec(source_delete)
            assert False
        finally:
            self.release_table(record_id)
            if self.task_is_running(task_name):
                self.stop_task_wait_it_paused(task_name)
            self.generate_task_url(task_name, data.get('task_type'))
            self.generate_inspect_url(task_name)
            logger.info(self.task_url)
            logger.info(self.inspect_url)
            try:
                _source.tapclient_connector.close()
                _target.tapclient_connector.close()
            except Exception as e:
                pass

    def TASK_INSPECT_TEMPLATE_INITIAL_CHECK_BreakPoint(self, parallel_data):
        data = None
        record_id = None
        task_name = None
        # 随机等待
        self.random_wait()
        try:
            data = self.lock_and_only_get_table(parallel_data)
            record_id = data.get('id')

            operate = data.pop('operate')
            operate_source = operate.get('source')
            source_info = operate_source.get('source_info')
            source_table = operate_source.get('table')
            operate_target = operate.get('target')
            target_info = operate_target.get('target_info')
            target_table = operate_target.get('table')

            if type(source_table) is list:
                pass
            else:
                data['task_config']['config']['name'] += source_table
            with allure.step('创建表获取'):
                task_name = data.get('task_config').get('config').get('name')

            # connector
            with allure.step('源数据库初始化'):
                _source = self.init_connector(source_info)
            with allure.step('目标数据库初始化'):
                _target = self.init_connector(target_info)
            _source.tapclient_connector.CURRENT_TABLE = source_table
            _target.tapclient_connector.CURRENT_TABLE = target_table

            source_where_column = operate_source.get('where')

            # stats check
            _stats = operate.get('stats_check').get('initial')
            _stats_initial = _stats.get('insert')
            # 多表处理
            if type(target_table) is list:
                self.drop_more_target_table(_target, target_table)
                source_delete = [_source.tapclient_connector.generate_delete(
                    source_where_column, moretableten
                ) for moretableten in source_table]
                with allure.step('执行前删除要插入的数据'):
                    _source.tapclient_connector.execMany(_source.tapclient_connector.exec, source_delete)
            else:
                self.drop_target_table(_target)
            # inspects info init
            inspect_init = {
                'source': source_info.get('name'),
                'target': target_info.get('name'),
                'table': target_table,
                'inspect_setting': {
                    # 'inspectMethod': 'field',
                    'inspectMethod': data.get('inspectMethod'),
                    'name': task_name
                }
            }

            with allure.step('创建任务'):
                task_info = self.create_data_copy_development(data)
                time.sleep(check_wait * 2)
                inspect_init['inspect_setting']['flowId'] = task_info.get('id')
            # initial stats insert 校验
            with allure.step('任务状态等待'):
                self.scheduled_task_wait_it_complete(task_name)
            self.release_table(record_id)
            self.func_wait(
                self.get_task_stats_insert,
                self.get_task_status,
                task_name,
                _stats_initial
            )
            with allure.step('initial数据校验'):
                self.create_inspects_mission(inspect_init)
                self.inspects_func_wait(
                    self.get_inspect_status,
                    self.get_inspect_result,
                    self.get_inspect_source_total,
                    task_name,
                    _stats_initial
                )
        finally:
            self.release_table(record_id)
            self.generate_task_url(task_name, data.get('task_type'))
            self.generate_inspect_url(task_name)
            logger.info(self.task_url)
            logger.info(self.inspect_url)
            try:
                _source.tapclient_connector.close()
                _target.tapclient_connector.close()
            except Exception as e:
                pass
